package protocol

import (
	"gitee.com/crack007/goose/core/server"
	"gitee.com/crack007/udp-penetrate/src/common/constant"
	"gitee.com/crack007/udp-penetrate/src/udpserver/service"
	"net"
)

// server接收到目标客户端的响应，通知发起的客户端进行连接
type ClientHandshakeRespProtocol struct {
	TargetHost string // 连接目标的公网ip
	TargetPort uint16 // 连接目标的公网端口
	OriginHost string // 发起的客户端公网ip
	OriginPort uint16 // 发起的客户端公网端口
	Uid        uint32 // 发起的客户端uid
}

func NewClientHandshakeRespProtocol() *ClientHandshakeRespProtocol {
	return &ClientHandshakeRespProtocol{}
}

func (p *ClientHandshakeRespProtocol) Code() uint32 {
	return constant.CMD_CTOCHANDSHAKE_RESP
}

// server处理
func (p *ClientHandshakeRespProtocol) Process(session *server.Session, clientConn *net.UDPConn) IProtocol {
	// 准备完毕，通知发起的客户端可以连接了
	ctoCHandshakeReqProtocol := NewCtoCHandshakeReqProtocol()
	ctoCHandshakeReqProtocol.TargetPort = p.TargetPort
	ctoCHandshakeReqProtocol.TargetHost = p.TargetHost
	// 查找发起客户端session
	originSession := service.UserService.GetSessionByUid(p.Uid)
	packData, err := PackData(ctoCHandshakeReqProtocol)
	if err != nil {
		return nil
	}
	originSession.AsyncSend(packData)
	return nil
}

func (p *ClientHandshakeRespProtocol) Marshall() []byte {
	data := &hostMeta{
		TargetHost: p.TargetHost,
		TargetPort: p.TargetPort,
		OriginHost: p.OriginHost,
		OriginPort: p.OriginPort,
		Uid:        p.Uid,
	}
	return marshalHostMeta(data)
}

func (p *ClientHandshakeRespProtocol) UnMarshall(data []byte) {
	host := unMarshalHostMeta(data)
	p.TargetPort = host.TargetPort
	p.TargetHost = host.TargetHost
	p.OriginHost = host.OriginHost
	p.OriginPort = host.OriginPort
	p.Uid = host.Uid
}
